package com.huilian.iotbox.data.service.impl;

import com.huilian.iotbox.data.dao.MemberStoreBalanceCommonDao;
import com.huilian.iotbox.data.dto.MemberStoreBalanceDto;
import com.huilian.iotbox.data.enums.MemberStoreBalanceStatusEnum;
import com.huilian.iotbox.data.po.MemberStoreBalance;
import com.huilian.iotbox.data.po.Order;
import com.huilian.iotbox.data.service.MemberStoreBalanceCommonService;
import com.huilian.iotbox.data.service.RabbitSenderCommonService;
import com.huilian.iotbox.data.vo.MemberStoreBalanceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class MemberStoreBalanceCommonServiceImpl implements MemberStoreBalanceCommonService {

    // 增加或减少游戏币重试次数
    private static int count = 10;
    @Autowired
    private RabbitSenderCommonService rabbitSenderCommonService;
    @Autowired
    private MemberStoreBalanceCommonDao memberStoreBalanceCommonDao;

    @Override
    public List<MemberStoreBalance> findAllByMemberId(Long id) {
        return memberStoreBalanceCommonDao.findAllByMemberId(id);
    }


    @Override
    public MemberStoreBalanceVo findBalance(MemberStoreBalanceDto memberStoreBalanceDto) {
        return memberStoreBalanceCommonDao.findMemberStoreBalanceByMerchantStoreId(memberStoreBalanceDto);
    }

    /**
     * 会员等级晋升，记录总消费额
     *
     * @param order
     */
    @Override
    public void updateOrderRecord(Order order) {
        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setMemberId(order.getMemberId());
        memberStoreBalanceDto.setMerchantStoreId(order.getMerchantStoreId());
        final MemberStoreBalanceVo balanceByMerchantStoreId = memberStoreBalanceCommonDao.findMemberStoreBalanceByMerchantStoreId(memberStoreBalanceDto);
        balanceByMerchantStoreId.setTotalPay(balanceByMerchantStoreId.getTotalPay().add(order.getTotalAmount()));
        balanceByMerchantStoreId.setLatelyPay(order.getGmtPayment());
        if (balanceByMerchantStoreId.getTotalPay().compareTo(new BigDecimal("20000")) > 0) {
            balanceByMerchantStoreId.setLevelPay(3);
        } else if (balanceByMerchantStoreId.getTotalPay().compareTo(new BigDecimal("5000")) > 0) {
            balanceByMerchantStoreId.setLevelPay(2);
        }
        memberStoreBalanceCommonDao.updateOrderRecord(balanceByMerchantStoreId);
    }

    /**
     * 注册 会员-场地 关联记录
     *
     * @param memberId
     * @param merchantStoreId
     * @param userId
     * @return
     */
    @Override
    public int add(Long memberId, Integer merchantStoreId, Integer userId, String registerDeviceNo) {

        if (StringUtils.isEmpty(merchantStoreId) || merchantStoreId.compareTo(-1) == 0) {
            throw new RuntimeException("设备未绑定场地");
        }

        MemberStoreBalanceVo memberStoreBalance = new MemberStoreBalanceVo();
        memberStoreBalance.setMemberId(memberId);
        memberStoreBalance.setMerchantStoreId(merchantStoreId);
        memberStoreBalance.setRegisterDeviceNo(registerDeviceNo);
        memberStoreBalance.setUserId(userId);
        memberStoreBalance.setMoneyRechargeBalance(BigDecimal.ZERO);
        memberStoreBalance.setMoneyDonateBalance(BigDecimal.ZERO);
        memberStoreBalance.setRechargeBalance(Integer.valueOf(0));
        memberStoreBalance.setDonateBalance(Integer.valueOf(0));
        memberStoreBalance.setLottery(Integer.valueOf(0));
        memberStoreBalance.setIntegral(Integer.valueOf(0));
        memberStoreBalance.setStatus(MemberStoreBalanceStatusEnum.NORMAL.getCode());

        return memberStoreBalanceCommonDao.insert(memberStoreBalance);
    }

    @Override
    public MemberStoreBalanceVo findOneMemberStoreBalanceById(Long memberStoreBalanceId) {
        return memberStoreBalanceCommonDao.findOneMemberStoreBalanceById(memberStoreBalanceId);
    }

    /**
     * 增加或减少游戏币前校验参数
     *
     * @param rechargeNum          充值游戏币数量
     * @param donateNum            赠送游戏币数量
     * @param memberStoreBalanceId 会员场地关联id
     * @param memberId             会员id
     * @param userId               商家id
     * @param merchantStoreId      场地id
     * @return
     */
    @Override
    public MemberStoreBalance addOrReduceMemberStoreBalanceBeforeCheckParam(int rechargeNum, int donateNum, long memberStoreBalanceId, long memberId, int userId, int merchantStoreId) {

        if (rechargeNum == 0 && donateNum == 0) {
            log.error("充值、赠送游戏币数量为0。rechargeNum=" + rechargeNum);
            log.error("充值、赠送游戏币数量为0。donateNum=" + donateNum);
            throw new RuntimeException("充值、赠送游戏币数量为0");
        }

        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setId(memberStoreBalanceId);
        MemberStoreBalance memberStoreBalance = memberStoreBalanceCommonDao.findOneMemberStoreBalanceByCondition(memberStoreBalanceDto);
        if (StringUtils.isEmpty(memberStoreBalance)) {
            log.error("会员场地关联id无效。memberStoreBalanceId=" + memberStoreBalanceId);
            throw new RuntimeException("会员场地关联id无效");
        }

        if (!memberStoreBalance.getMemberId().equals(memberId)) {
            log.error("会员id不匹配。memberId=" + memberId);
            log.error("会员id不匹配。memberId=" + memberStoreBalance.getMemberId());
            throw new RuntimeException("会员id不匹配");
        }

        if (userId != memberStoreBalance.getUserId()) {
            log.error("会员场地关联userId无效。userId=" + userId);
            log.error("会员场地关联userId无效。userId=" + memberStoreBalance.getUserId());
            throw new RuntimeException("会员场地关联userId无效");
        }

//        if (merchantStoreId != memberStoreBalance.getMerchantStoreId()) {
//            log.error("会员场地关联merchantStoreId无效。merchantStoreId=" + merchantStoreId);
//            throw new RuntimeException("会员场地关联merchantStoreId无效");
//        }

        return memberStoreBalance;
    }

    /**
     * 增加游戏币余额
     *
     * @param runCount             当前第几次运行，传值 1
     * @param rechargeNum          充值游戏币数量
     * @param donateNum            赠送游戏币数量
     * @param memberStoreBalanceId 会员场地关联id
     * @param memberId             会员id
     * @param userId               商家id
     * @param merchantStoreId      场地id
     * @return
     */
    @Override
    public int addMemberStoreBalance(int runCount, int rechargeNum, int donateNum, long memberStoreBalanceId, long memberId, int userId, int merchantStoreId) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalanceId + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance memberStoreBalance
                = addOrReduceMemberStoreBalanceBeforeCheckParam(rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId);

        int row = memberStoreBalanceCommonDao.addMemberStoreBalance(rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId, memberStoreBalance.getVersionId());

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.addMemberStoreBalance(runCount + 1, rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId);
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalanceId + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }

    /**
     * 减少游戏币余额
     *
     * @param runCount             当前第几次运行，传值 1
     * @param rechargeNum          充值游戏币数量
     * @param donateNum            赠送游戏币数量
     * @param memberStoreBalanceId 会员场地关联id
     * @param memberId             会员id
     * @param userId               商家id
     * @param merchantStoreId      场地id
     * @return
     */
    @Override
    public int reduceMemberStoreBalance(int runCount, int rechargeNum, int donateNum, Long memberStoreBalanceId, Long memberId, Integer userId, Integer merchantStoreId) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalanceId + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance memberStoreBalance
                = addOrReduceMemberStoreBalanceBeforeCheckParam(rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId);

        if (memberStoreBalance.getRechargeBalance() < rechargeNum || memberStoreBalance.getDonateBalance() < donateNum) {
            if (runCount >= count) {
                return 0;
            }
            return this.reduceMemberStoreBalance(runCount + 1, rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId);
        }

        int row = memberStoreBalanceCommonDao.reduceMemberStoreBalance(rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId, memberStoreBalance.getVersionId());

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.reduceMemberStoreBalance(runCount + 1, rechargeNum, donateNum, memberStoreBalanceId, memberId, userId, merchantStoreId);
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalanceId + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }

    /**
     * 增加人民币余额
     *
     * @param runCount           当前第几次运行，传值 1
     * @param memberStoreBalance
     * @return
     */
    @Override
    public int addMemberStoreMoneyBalance(int runCount, MemberStoreBalance memberStoreBalance) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalance.getId() + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance msb = addOrReduceMemberStoreMoneyBalanceBeforeCheckParam(
                memberStoreBalance.getMoneyRechargeBalance(),
                memberStoreBalance.getMoneyDonateBalance(),
                memberStoreBalance.getId(),
                memberStoreBalance.getMemberId(),
                memberStoreBalance.getUserId(),
                memberStoreBalance.getMerchantStoreId()
        );

        memberStoreBalance.setVersionId(msb.getVersionId());
        int row = memberStoreBalanceCommonDao.addMemberStoreMoneyBalance(memberStoreBalance);

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalance.getId() + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.addMemberStoreMoneyBalance(runCount + 1, memberStoreBalance);
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalance.getId() + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalance.getId() + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }


    /**
     * 减少人民币余额
     *
     * @param runCount           当前第几次运行，传值 1
     * @param memberStoreBalance
     * @return
     */
    @Override
    public int reduceMemberStoreMoneyBalance(int runCount, MemberStoreBalance memberStoreBalance) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalance.getId() + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance msb = addOrReduceMemberStoreMoneyBalanceBeforeCheckParam(
                memberStoreBalance.getMoneyRechargeBalance(),
                memberStoreBalance.getMoneyDonateBalance(),
                memberStoreBalance.getId(),
                memberStoreBalance.getMemberId(),
                memberStoreBalance.getUserId(),
                memberStoreBalance.getMerchantStoreId()
        );

        memberStoreBalance.setVersionId(msb.getVersionId());
        int row = memberStoreBalanceCommonDao.reduceMemberStoreChargeBalance(memberStoreBalance);

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalance.getId() + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.reduceMemberStoreMoneyBalance(runCount + 1, memberStoreBalance);
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalance.getId() + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalance.getId() + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }


    /**
     * 增加或减少人民币余额前校验参数
     *
     * @return
     */
    @Override
    public MemberStoreBalance addOrReduceMemberStoreMoneyBalanceBeforeCheckParam(
            BigDecimal moneyRechargeBalance,
            BigDecimal moneyDonateBalance,
            long memberStoreBalanceId,
            long memberId,
            int userId,
            int merchantStoreId
    ) {

        if (moneyRechargeBalance.compareTo(BigDecimal.ZERO) == 0 && moneyDonateBalance.compareTo(BigDecimal.ZERO) == 0) {
            log.error("人民币充值余额为0。moneyRechargeBalance=" + moneyRechargeBalance);
            log.error("人民币赠送余额为0。moneyDonateBalance=" + moneyDonateBalance);
            throw new RuntimeException("人民币充值、赠送余额为0");
        }

        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setId(memberStoreBalanceId);
        MemberStoreBalance msb = memberStoreBalanceCommonDao.findOneMemberStoreBalanceByCondition(memberStoreBalanceDto);
        if (StringUtils.isEmpty(msb)) {
            log.error("人民币充值、赠送余额为0。memberStoreBalanceId=" + memberStoreBalanceId);
            throw new RuntimeException("会员场地关联id无效");
        }

        if (!msb.getMemberId().equals(memberId)) {
            log.error("会员id不匹配。memberId=" + memberId);
            throw new RuntimeException("会员id不匹配");
        }

        if (msb.getUserId().compareTo(userId) != 0) {
            log.error("会员场地关联id无效。userId=" + userId);
            throw new RuntimeException("会员场地关联id无效");
        }

        if (msb.getMerchantStoreId().compareTo(merchantStoreId) != 0) {
            log.error("会员场地关联id无效。merchantStoreId=" + merchantStoreId);
            throw new RuntimeException("会员场地关联id无效");
        }

        return msb;
    }

    /**
     * 添加积分
     *
     * @param runCount
     * @param integral
     * @param memberStoreBalanceId
     * @param memberId
     * @param userId
     * @param merchantStoreId
     * @return
     */
    @Override
    public int addMemberStoreIntegralBalance(
            int runCount,
            Integer integral,
            long memberStoreBalanceId,
            long memberId,
            Integer userId,
            Integer merchantStoreId
    ) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalanceId + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance memberStoreBalance = addOrReduceMemberStoreIntegralBalanceBeforeCheckParam(
                integral,
                memberStoreBalanceId,
                memberId,
                userId,
                merchantStoreId
        );

        int row = memberStoreBalanceCommonDao.addMemberStoreIntegralBalance(
                integral,
                memberStoreBalanceId,
                memberId,
                userId,
                merchantStoreId,
                memberStoreBalance.getVersionId()
        );

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.addMemberStoreIntegralBalance(
                    runCount + 1,
                    integral,
                    memberStoreBalanceId,
                    memberId,
                    userId,
                    merchantStoreId
            );
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalanceId + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }

    /**
     * 增加或减少积分余额前校验参数
     *
     * @param integral
     * @param memberStoreBalanceId
     * @param memberId
     * @param userId
     * @param merchantStoreId
     * @return
     */
    private MemberStoreBalance addOrReduceMemberStoreIntegralBalanceBeforeCheckParam(
            Integer integral,
            Long memberStoreBalanceId,
            Long memberId,
            Integer userId,
            Integer merchantStoreId
    ) {

        if (integral == 0) {
            log.error("积分数量为0。integral=" + integral);
            throw new RuntimeException("积分数量为0");
        }

        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setId(memberStoreBalanceId);
        MemberStoreBalance memberStoreBalance = memberStoreBalanceCommonDao.findOneMemberStoreBalanceByCondition(memberStoreBalanceDto);
        if (StringUtils.isEmpty(memberStoreBalance)) {
            log.error("会员场地关联id无效。memberStoreBalanceId=" + memberStoreBalanceId);
            throw new RuntimeException("会员场地关联id无效");
        }

        if (!memberStoreBalance.getMemberId().equals(memberId)) {
            log.error("会员id不匹配。memberId=" + memberId);
            log.error("会员id不匹配。memberId=" + memberStoreBalance.getMemberId());
            throw new RuntimeException("会员id不匹配");
        }

        if (!Objects.equals(userId, memberStoreBalance.getUserId())) {
            log.error("会员场地关联userId无效。userId=" + userId);
            log.error("会员场地关联userId无效。userId=" + memberStoreBalance.getUserId());
            throw new RuntimeException("会员场地关联userId无效");
        }

        if (memberStoreBalance.getMerchantStoreId().compareTo(merchantStoreId) != 0) {
            log.error("会员场地关联id无效。merchantStoreId=" + merchantStoreId);
            throw new RuntimeException("会员场地关联id无效");
        }

        return memberStoreBalance;
    }


    /**
     * 添加彩票
     *
     * @param runCount
     * @param lottery
     * @param memberStoreBalanceId
     * @param memberId
     * @param userId
     * @param merchantStoreId
     * @return
     */
    @Override
    public int addMemberStoreLotteryBalance(
            int runCount,
            Integer lottery,
            long memberStoreBalanceId,
            long memberId,
            Integer userId,
            Integer merchantStoreId
    ) {
        long begin = System.currentTimeMillis();
        log.info(memberStoreBalanceId + "线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        MemberStoreBalance memberStoreBalance = addOrReduceLotteryBalanceBeforeCheckParam(
                lottery,
                memberStoreBalanceId,
                memberId,
                userId,
                merchantStoreId
        );

        int row = memberStoreBalanceCommonDao.addMemberStoreLotteryBalance(
                lottery,
                memberStoreBalanceId,
                memberId,
                userId,
                merchantStoreId,
                memberStoreBalance.getVersionId()
        );

        if (row == 0 && runCount < count) {
            log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return this.addMemberStoreLotteryBalance(
                    runCount + 1,
                    lottery,
                    memberStoreBalanceId,
                    memberId,
                    userId,
                    merchantStoreId
            );
        } else if (row == 0 && runCount >= count) {
            log.info(memberStoreBalanceId + "执行次数达到" + count + "次，row=0");
        }
        log.info(memberStoreBalanceId + "业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
        return row;
    }

    @Override
    public int updateTotalPayById(MemberStoreBalance updateMemberStoreBalance) {
        return memberStoreBalanceCommonDao.updateTotalPayById(updateMemberStoreBalance);
    }

    @Override
    public MemberStoreBalanceVo findMemberStoreBalanceByMerchantStoreId(MemberStoreBalanceDto memberStoreBalanceDto) {
        return memberStoreBalanceCommonDao.findMemberStoreBalanceByMerchantStoreId(memberStoreBalanceDto);
    }

    @Override
    public MemberStoreBalanceVo queryMemberStoreBalance(Integer merchantStoreId, Long memberId) {
        return memberStoreBalanceCommonDao.queryMemberStoreBalanceVo(merchantStoreId, memberId);
    }

    /**
     * 增加会员余额（乐观锁）<br/>
     * 需要参数：<br/>
     * memberId <br/>
     * merchantStoreId  <br/>
     * userId   <br/>
     * 和对应需要增加的数额即可
     *
     * @param runCount
     * @param memberStoreBalanceDto
     * @return
     * @throws Exception
     */
    @Override
    public MemberStoreBalanceDto addBalance(int runCount, MemberStoreBalanceDto memberStoreBalanceDto) throws Exception {
        long begin = System.currentTimeMillis();
        log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "增加余额线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        log.info("参数为：" + memberStoreBalanceDto);
        MemberStoreBalanceVo memberStoreBalanceVo = memberStoreBalanceCommonDao.findByMemberIdAndMerchantStoreId(memberStoreBalanceDto);
        //memberStoreBalanceVo如果为空，创新的
        if (ObjectUtils.isEmpty(memberStoreBalanceVo)) {
            MemberStoreBalanceDto newBalance = new MemberStoreBalanceDto();
            newBalance.setMemberId(memberStoreBalanceDto.getMemberId());
            newBalance.setMerchantStoreId(memberStoreBalanceDto.getMerchantStoreId());
            newBalance.setRegisterDeviceNo(null);
            newBalance.setUserId(memberStoreBalanceDto.getUserId());
            newBalance.setRechargeBalance(0);
            newBalance.setDonateBalance(0);
            newBalance.setIntegral(0);
            newBalance.setLottery(0);
            newBalance.setMoneyRechargeBalance(BigDecimal.ZERO);
            newBalance.setMoneyDonateBalance(BigDecimal.ZERO);
            newBalance.setStatus(MemberStoreBalanceStatusEnum.NORMAL.getCode());
            memberStoreBalanceCommonDao.add(newBalance);
            memberStoreBalanceVo = new MemberStoreBalanceVo();
            memberStoreBalanceVo.setId(newBalance.getId());
            memberStoreBalanceVo.setMoneyRechargeBalance(newBalance.getMoneyRechargeBalance());
            memberStoreBalanceVo.setMoneyDonateBalance(newBalance.getMoneyDonateBalance());
            memberStoreBalanceVo.setRechargeBalance(newBalance.getRechargeBalance());
            memberStoreBalanceVo.setDonateBalance(newBalance.getDonateBalance());
            memberStoreBalanceVo.setLottery(newBalance.getLottery());
            memberStoreBalanceVo.setIntegral(newBalance.getIntegral());
        }
        memberStoreBalanceDto.setId(memberStoreBalanceVo.getId());
        memberStoreBalanceDto.setMoneyRechargeBalance(memberStoreBalanceVo.getMoneyRechargeBalance());
        memberStoreBalanceDto.setMoneyDonateBalance(memberStoreBalanceVo.getMoneyDonateBalance());
        memberStoreBalanceDto.setRechargeBalance(memberStoreBalanceVo.getRechargeBalance());
        memberStoreBalanceDto.setDonateBalance(memberStoreBalanceVo.getDonateBalance());
        memberStoreBalanceDto.setLottery(memberStoreBalanceVo.getLottery());
        memberStoreBalanceDto.setIntegral(memberStoreBalanceVo.getIntegral());

        MemberStoreBalanceDto updateMemberStoreBalanceDto = new MemberStoreBalanceDto();
        updateMemberStoreBalanceDto.setId(memberStoreBalanceDto.getId());
        updateMemberStoreBalanceDto.setMemberId(memberStoreBalanceDto.getMemberId());
        updateMemberStoreBalanceDto.setUserId(memberStoreBalanceDto.getUserId());
        updateMemberStoreBalanceDto.setMerchantStoreId(memberStoreBalanceDto.getMerchantStoreId());

        //人民币充值余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddMoneyRechargeBalance())) {
            updateMemberStoreBalanceDto.setMoneyRechargeBalance(memberStoreBalanceVo.getMoneyRechargeBalance().add(memberStoreBalanceDto.getAddMoneyRechargeBalance()));
            memberStoreBalanceDto.setMoneyRechargeBalance(updateMemberStoreBalanceDto.getMoneyRechargeBalance());
        }
        //人民币赠送余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddMoneyDonateBalance())) {
            updateMemberStoreBalanceDto.setMoneyDonateBalance(memberStoreBalanceVo.getMoneyDonateBalance().add(memberStoreBalanceDto.getAddMoneyDonateBalance()));
            memberStoreBalanceDto.setMoneyDonateBalance(updateMemberStoreBalanceDto.getMoneyDonateBalance());
        }
        //充值游戏币余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddRechargeBalance())) {
            updateMemberStoreBalanceDto.setRechargeBalance(memberStoreBalanceVo.getRechargeBalance() + memberStoreBalanceDto.getAddRechargeBalance());
            memberStoreBalanceDto.setRechargeBalance(updateMemberStoreBalanceDto.getRechargeBalance());
        }
        //赠送游戏币余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddDonateBalance())) {
            updateMemberStoreBalanceDto.setDonateBalance(memberStoreBalanceVo.getDonateBalance() + memberStoreBalanceDto.getAddDonateBalance());
            memberStoreBalanceDto.setDonateBalance(updateMemberStoreBalanceDto.getDonateBalance());
        }
        //彩票余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddLottery())) {
            updateMemberStoreBalanceDto.setLottery(memberStoreBalanceVo.getLottery() + memberStoreBalanceDto.getAddLottery());
            memberStoreBalanceDto.setLottery(updateMemberStoreBalanceDto.getLottery());
        }
        //积分余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getAddIntegral())) {
            updateMemberStoreBalanceDto.setIntegral(memberStoreBalanceVo.getIntegral() + memberStoreBalanceDto.getAddIntegral());
            memberStoreBalanceDto.setIntegral(updateMemberStoreBalanceDto.getIntegral());
        }
        updateMemberStoreBalanceDto.setVersionId(memberStoreBalanceVo.getVersionId());

        int i = memberStoreBalanceCommonDao.updateBalance(updateMemberStoreBalanceDto);
        if (i > 0) {
            log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "增加余额业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return memberStoreBalanceDto;
        } else {
            if (count >= runCount) {
                return this.addBalance(++runCount, memberStoreBalanceDto);
            } else {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "增加余额失败！memberStoreBalanceId为" + memberStoreBalanceDto.getId());
                throw new Exception("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "增加余额失败！memberStoreBalanceId为" + memberStoreBalanceDto.getId());
            }
        }
    }

    /**
     * 增加或减少积分余额前校验参数
     *
     * @param lottery
     * @param memberStoreBalanceId
     * @param memberId
     * @param userId
     * @param merchantStoreId
     * @return
     */
    private MemberStoreBalance addOrReduceLotteryBalanceBeforeCheckParam(
            Integer lottery,
            Long memberStoreBalanceId,
            Long memberId,
            Integer userId,
            Integer merchantStoreId
    ) {

        if (lottery == 0) {
            log.error("彩票数量为0。integral=" + lottery);
            throw new RuntimeException("彩票数量为0");
        }

        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setId(memberStoreBalanceId);
        MemberStoreBalance memberStoreBalance = memberStoreBalanceCommonDao.findOneMemberStoreBalanceByCondition(memberStoreBalanceDto);
        if (StringUtils.isEmpty(memberStoreBalance)) {
            log.error("会员场地关联id无效。memberStoreBalanceId=" + memberStoreBalanceId);
            throw new RuntimeException("会员场地关联id无效");
        }

        if (!memberStoreBalance.getMemberId().equals(memberId)) {
            log.error("会员id不匹配。memberId=" + memberId);
            log.error("会员id不匹配。memberId=" + memberStoreBalance.getMemberId());
            throw new RuntimeException("会员id不匹配");
        }

        if (!Objects.equals(userId, memberStoreBalance.getUserId())) {
            log.error("会员场地关联userId无效。userId=" + userId);
            log.error("会员场地关联userId无效。userId=" + memberStoreBalance.getUserId());
            throw new RuntimeException("会员场地关联userId无效");
        }

        if (memberStoreBalance.getMerchantStoreId().compareTo(merchantStoreId) != 0) {
            log.error("会员场地关联id无效。merchantStoreId=" + merchantStoreId);
            throw new RuntimeException("会员场地关联id无效");
        }

        return memberStoreBalance;
    }
}
